from openai import OpenAI, APIConnectionError, RateLimitError
import time
import logging
import os
from typing import Optional
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

logger = logging.getLogger(__name__)

class ImprovedKimiClient:
    """改进的Kimi API客户端，基于参考实现的最佳实践"""

    def __init__(self, api_key: Optional[str] = None, model='moonshot-v1-8k', try_times=5):
        """
        初始化Kimi客户端

        Args:
            api_key: API密钥，如果不提供则从环境变量读取
            model: 使用的模型名称
            try_times: 失败重试次数
        """
        self.api_key = api_key or os.getenv("KIMI_API_KEY", "").strip()

        if not self.api_key:
            raise ValueError("未配置KIMI_API_KEY环境变量")

        self.client = OpenAI(
            api_key=self.api_key,
            base_url="https://api.moonshot.cn/v1"
        )
        self.model = model
        self.try_times = try_times

        logger.info(f"🤖 Kimi客户端初始化完成，模型: {model}")
        logger.info(f"🔑 API密钥前8位: {self.api_key[:8]}...")

    def request(self, user_content: str, system_prompt: str) -> str:
        """
        发送请求到Kimi API

        Args:
            user_content: 用户内容
            system_prompt: 系统提示词

        Returns:
            API响应内容
        """
        logger.info(f"📤 发送请求到Kimi API，用户内容长度: {len(user_content)}字符")

        messages = [
            {'role': 'system', 'content': system_prompt},
            {'role': 'user', 'content': user_content}
        ]

        for attempt in range(self.try_times):
            try:
                response = self.client.chat.completions.create(
                    model=self.model,
                    messages=messages,
                    temperature=0.7,
                    max_tokens=4000
                )

                result = response.choices[0].message.content
                logger.info(f"✅ Kimi API调用成功，响应长度: {len(result) if result else 0}字符")
                return result

            except RateLimitError as e:
                wait_time = (attempt + 1) * 5
                logger.warning(f"⚠️ 触发速率限制，{wait_time}秒后重试 (尝试 {attempt + 1}/{self.try_times})")
                time.sleep(wait_time)

            except APIConnectionError as e:
                wait_time = (attempt + 1) * 3
                logger.warning(f"⚠️ 连接错误，{wait_time}秒后重试 (尝试 {attempt + 1}/{self.try_times}): {e}")
                time.sleep(wait_time)

            except Exception as e:
                logger.error(f"❌ API调用失败 (尝试 {attempt + 1}/{self.try_times}): {e}")
                if attempt == self.try_times - 1:
                    raise
                time.sleep(2)

        raise Exception(f"经过{self.try_times}次尝试后仍无法连接到Kimi API")

class MeetingMinutesRoles:
    """会议纪要角色系统，基于参考实现的角色提示词"""

    def __init__(self, llm_client: ImprovedKimiClient):
        self.llm_client = llm_client
        self.prompts_dir = os.getenv("PROMPTS_DIR", "../prompts")
        logger.info(f"📁 提示词目录: {self.prompts_dir}")

    def _read_prompt(self, filename: str) -> str:
        """读取提示词文件"""
        file_path = os.path.join(self.prompts_dir, filename)
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
            logger.info(f"📖 成功读取提示词文件: {filename}")
            return content
        except FileNotFoundError:
            logger.error(f"❌ 提示词文件不存在: {file_path}")
            # 返回默认提示词
            return self._get_default_prompt(filename)

    def _get_default_prompt(self, filename: str) -> str:
        """获取默认提示词"""
        if "MeetingSecretary" in filename:
            return """你是会议记录员，负责将会议录音转录成结构化的文字记录。
请保持原意的基础上，整理对话内容，去除重复和口语化表达，使其更易阅读。"""
        elif "SummaryWriter" in filename:
            return """你是会议总结编辑员，负责提炼会议讨论的要点和结论。
请识别关键信息、分析观点、总结结论，生成精炼的文本摘要。"""
        elif "MeetingMinutesEditor" in filename:
            return """你是会议纪要编辑员，负责将转录内容和总结整理成标准的会议纪要格式。
请按照标准的会议纪要模板，包含会议基本信息、主要议题、讨论要点、决议事项等。"""
        else:
            return "你是专业的会议纪要助手，请帮助生成高质量的会议纪要。"

    def generate_meeting_minutes(self, transcript_text: str, meeting_title: str, template_name: str = "标准") -> str:
        """
        使用角色链生成会议纪要

        Args:
            transcript_text: 转录文本
            meeting_title: 会议标题
            template_name: 模板名称

        Returns:
            完整的会议纪要
        """
        logger.info(f"🚀 开始生成会议纪要: {meeting_title}")

        # 步骤1: 会议记录员处理转录内容
        logger.info("📝 步骤1: 会议记录员整理转录内容")
        secretary_prompt = self._read_prompt("MeetingSecretary.md")

        structured_transcript = self.llm_client.request(
            f"""请整理以下会议转录内容：

会议标题：{meeting_title}

转录内容：
{transcript_text}

请将上述转录内容整理成结构化的文字记录，保持原意，去除重复和口语化表达。""",
            secretary_prompt
        )

        # 步骤2: 总结编辑员提炼要点
        logger.info("📊 步骤2: 总结编辑员提炼要点")
        summary_prompt = self._read_prompt("SummaryWriter.md")

        summary = self.llm_client.request(
            f"""请总结以下会议记录的要点：

会议标题：{meeting_title}

整理后的转录内容：
{structured_transcript}

请提炼关键信息、分析观点、总结结论，生成不少于500字的精炼摘要。""",
            summary_prompt
        )

        # 步骤3: 纪要编辑员生成最终纪要
        logger.info("📋 步骤3: 纪要编辑员生成最终纪要")
        editor_prompt = self._read_prompt("MeetingMinutesEditor.md")

        final_minutes = self.llm_client.request(
            f"""请生成完整的会议纪要：

会议标题：{meeting_title}
使用模板：{template_name}

转录内容：
{transcript_text}

会议总结：
{summary}

请按照标准会议纪要格式，生成包含以下内容的完整纪要：
1. 会议基本信息
2. 主要议题和讨论要点
3. 关键结论和决议
4. 后续行动计划""",
            editor_prompt
        )

        logger.info("✅ 会议纪要生成完成")
        return final_minutes